//-- GUI EDITABLE: { !function(global) { 'use strict'; function GUIEditable(elem, settings) { this.$element = jQuery(elem); this.__SETTINGS = jQuery.extend({ inputSelector: '.' + GUIEditable.JS_CLASS_INPUT, overflowOffset: 0, enableKeyboard: true, editByClick: true, saveByClick: true, cancelByClick: false, allowEmpty: true, classPlaceholder: GUIEditable.JS_CLASS__PLACEHOLDER, classOverflow: GUIEditable.JS_CLASS__OVERFLOW, classEditing: GUIEditable.JS_CLASS__EDITING }, this.$element.data(GUIEditable.DATA) || {}, settings || {}); this.__construct(); } //-- CONST: { Object.defineProperties(GUIEditable, { 'NAMESPACE_DATA': { value: (global.NAMESPACE_DATA ? (global.NAMESPACE_DATA + '-') : '') + 'gui-editable' }, 'NAMESPACE_JS_CLASS': { value: (global.NAMESPACE_JS_CLASS ? (global.NAMESPACE_JS_CLASS + '-') : '') + 'GUI-Editable' }, 'NAMESPACE_EVENT': { value: (global.NAMESPACE_EVENT ? (global.NAMESPACE_EVENT + ':') : '') + 'gui:editable' } }); Object.defineProperties(GUIEditable, { 'DATA': { value: GUIEditable.NAMESPACE_DATA }, 'JS_CLASS': { value: 'JS-' + GUIEditable.NAMESPACE_JS_CLASS }, 'EVENT_PREFIX': { value: 'js:' + GUIEditable.NAMESPACE_EVENT } }); Object.defineProperties(GUIEditable, { 'JS_CLASS__PLACEHOLDER': { value: GUIEditable.JS_CLASS + '-placeholder' }, 'JS_CLASS__OVERFLOW': { value: GUIEditable.JS_CLASS + '-overflow' }, 'JS_CLASS__EDITING': { value: GUIEditable.JS_CLASS + '-editing' }, 'JS_CLASS_INPUT': { value: GUIEditable.JS_CLASS + '-Input' }, 'JS_CLASS_VIEW': { value: GUIEditable.JS_CLASS + '-View' }, 'JS_CLASS_VALUE': { value: GUIEditable.JS_CLASS + '-Value' }, 'JS_CLASS_EDIT': { value: GUIEditable.JS_CLASS + '-Edit' }, 'JS_CLASS_SAVE': { value: GUIEditable.JS_CLASS + '-Save' }, 'JS_CLASS_CANCEL': { value: GUIEditable.JS_CLASS + '-Cancel' }, 'JS_CLASS_RESET': { value: GUIEditable.JS_CLASS + '-Reset' }, 'EVENT_INIT': { value: GUIEditable.EVENT_PREFIX + ':init' }, 'EVENT_READY': { value: GUIEditable.EVENT_PREFIX + ':ready' }, 'EVENT_CHANGE': { value: GUIEditable.EVENT_PREFIX + ':change' }, 'EVENT_EDIT': { value: GUIEditable.EVENT_PREFIX + ':edit' }, 'EVENT_SAVE': { value: GUIEditable.EVENT_PREFIX + ':save' }, 'EVENT_CANCEL': { value: GUIEditable.EVENT_PREFIX + ':cancel' }, 'EVENT_RESET': { value: GUIEditable.EVENT_PREFIX + ':reset' } }); //-- } /const. GUIEditable.prototype.__construct = function __construct() { this.$viewport = jQuery(document); this.$input = this.$element.find(this.__SETTINGS.inputSelector); this.$view = this.$element.find('.' + GUIEditable.JS_CLASS_VIEW); this.$value = this.$element.find('.' + GUIEditable.JS_CLASS_VALUE); this.$edit = this.$element.find('.' + GUIEditable.JS_CLASS_EDIT); this.$save = this.$element.find('.' + GUIEditable.JS_CLASS_SAVE); this.$cancel = this.$element.find('.' + GUIEditable.JS_CLASS_CANCEL); this.$reset = this.$element.find('.' + GUIEditable.JS_CLASS_RESET); this._default = this._getValue(false); this._isEditing = false; Object.defineProperty(this, 'value', { get: this._getValue, set: this._setValue }); this.__init(); }; GUIEditable.prototype.__init = function __init() { var changeEvents = [ 'change', 'input', ''].join('.' + GUIEditable.JS_CLASS + ' '); this.$element.trigger(GUIEditable.EVENT_INIT, { instance: this }); this.$input.on(changeEvents, this._change.bind(this)); this.$edit.on('click.' + GUIEditable.JS_CLASS, this.toggle.bind(this, undefined)); this.$save.on('click.' + GUIEditable.JS_CLASS, this.save.bind(this)); this.$cancel.on('click.' + GUIEditable.JS_CLASS, this.cancel.bind(this)); this.$reset.on('click.' + GUIEditable.JS_CLASS, this.reset.bind(this, undefined)); if (this.__SETTINGS.editByClick) { this.$view.on('click.' + GUIEditable.JS_CLASS, this._editByClick.bind(this)); } this.cancel(); this.__ready(); }; GUIEditable.prototype.__ready = function __ready() { this.$element .removeAttr('data-' + GUIEditable.DATA) .data(GUIEditable.DATA, { instance: this, __SETTINGS: this.$element.data(GUIEditable.DATA) || {} }) .trigger(GUIEditable.EVENT_READY, { instance: this }); }; GUIEditable.prototype._getValue = function _getValue(fromInput) { return (!arguments.length || fromInput === true ? this.$input.val() : this.$value.text()).trim(); }; GUIEditable.prototype._setValue = function _setValue(value) { value = ('' + value).trim(); this.$input.val(value); this.$value.text(value); if (!value) { if (this.__SETTINGS.allowEmpty) { this.$element .addClass(GUIEditable.JS_CLASS__PLACEHOLDER) .addClass(this.__SETTINGS.classPlaceholder); } else { this.toggle(true); } } else { this.$element .removeClass(GUIEditable.JS_CLASS__PLACEHOLDER) .removeClass(this.__SETTINGS.classPlaceholder); } this._redraw(value); }; GUIEditable.prototype._enableKeyboard = function _enableKeyboard(isEnable) { if (!this.__SETTINGS.enableKeyboard) { return; } this.$viewport.off('keyup.' + GUIEditable.JS_CLASS); if (isEnable) { this.$viewport.on('keyup.' + GUIEditable.JS_CLASS, this._keyboard.bind(this)); } }; GUIEditable.prototype._keyboard = function _keyboard(e) { switch (e.keyCode) { case Keyboard.KEY_CODE.ESC: this.cancel(); break; case Keyboard.KEY_CODE.ENTER: this.save(); break; default: break; } }; GUIEditable.prototype._editByClick = function _editByClick(e) { this.toggle(true); }; GUIEditable.prototype._saveByClick = function _saveByClick(e) { if (!jQuery(e.target).closest(this.$element).length) { this.save(); } }; GUIEditable.prototype._cancelByClick = function _cancelByClick(e) { if (!jQuery(e.target).closest(this.$element).length) { this.cancel(); } }; GUIEditable.prototype._redraw = function _redraw(value) { var title = ''; this.$element .removeClass(GUICombo.JS_CLASS__OVERFLOW) .removeClass(this.__SETTINGS.classOverflow); if (this.$value.outerWidth(true) - this.$view.outerWidth(true) > this.__SETTINGS.overflowOffset) { this.$element .addClass(GUICombo.JS_CLASS__OVERFLOW) .addClass(this.__SETTINGS.classOverflow); } this.$view.prop('title', title); }; GUIEditable.prototype._change = function _change() { this.$element.trigger(GUIEditable.EVENT_CHANGE, { instance: this }); }; GUIEditable.prototype.isDisabled = function isDisabled() { return this.$input.prop('disabled'); }; GUIEditable.prototype.isDirty = function isDirty() { return this._getValue() !== this._default; }; GUIEditable.prototype.isEmpty = function isEmpty() { return this._getValue().search(/\S/gim) === -1; }; GUIEditable.prototype._open = function _open() { if (this._isEditing === true) { return; } this.$element .removeClass(GUIEditable.JS_CLASS__PLACEHOLDER) .removeClass(this.__SETTINGS.classPlaceholder) .removeClass(GUIEditable.JS_CLASS__OVERFLOW) .removeClass(this.__SETTINGS.classOverflow) .addClass(GUIEditable.JS_CLASS__EDITING) .addClass(this.__SETTINGS.classEditing); this.$input .off('focus.' + GUIEditable.JS_CLASS) .on('focus.' + GUIEditable.JS_CLASS, this._enableKeyboard.bind(this, true)) .off('blur.' + GUIEditable.JS_CLASS) .on('blur.' + GUIEditable.JS_CLASS, this._enableKeyboard.bind(this, false)); if (this.__SETTINGS.saveByClick) { this.$viewport .off('click.' + GUIEditable.JS_CLASS) .on('click.' + GUIEditable.JS_CLASS, this._saveByClick.bind(this)); } else if (this.__SETTINGS.cancelByClick) { this.$viewport .off('click.' + GUIEditable.JS_CLASS) .on('click.' + GUIEditable.JS_CLASS, this._cancelByClick.bind(this)); } this.$input.trigger('focus'); this.$element.trigger(GUIEditable.EVENT_EDIT, { instance: this }); }; GUIEditable.prototype._close = function _close() { if (this._isEditing === false) { return; } this.$element .removeClass(GUIEditable.JS_CLASS__EDITING) .removeClass(this.__SETTINGS.classEditing); this.$input .off('focus.' + GUIEditable.JS_CLASS) .off('blur.' + GUIEditable.JS_CLASS); if (this.__SETTINGS.saveByClick || this.__SETTINGS.cancelByClick) { this.$viewport.off('click.' + GUIEditable.JS_CLASS); } this.$input.trigger('blur'); }; GUIEditable.prototype.toggle = function toggle(force) { if (!this.isDisabled()){ var isEditing = force === true || force === false ? force : !this._isEditing; if (isEditing) { this._open(); } else { if (!this.isEmpty() || this.__SETTINGS.allowEmpty) { this._close(); } else { this._open(); isEditing = true; } } this._isEditing = isEditing; } return this; }; GUIEditable.prototype.edit = function edit() { if (!this.isDisabled()){ this.toggle(true); } return this; }; GUIEditable.prototype.save = function save() { if (!this.isDisabled()){ var value = this._getValue(); this._setValue(value); this.toggle(false); if (!this._isEditing) { this.$element.trigger(GUIEditable.EVENT_SAVE, { instance: this, data: { value: value } }); return value; } } return false; }; GUIEditable.prototype.cancel = function cancel() { if (!this.isDisabled()){ var value = this._getValue(false); this._setValue(value); this.toggle(false); this.$element.trigger(GUIEditable.EVENT_CANCEL, { instance: this }); } return this; }; GUIEditable.prototype.reset = function reset(value) { if (!this.isDisabled()){ if (value) { this._default = value; } this._setValue(this._default); this.$element.trigger(GUIEditable.EVENT_RESET, { instance: this }); } return this; }; GUIEditable.prototype.disable = function disable(isDisabled) { this.$input.prop('disabled', isDisabled); return this; }; global.GUIEditable = GUIEditable; }(this); //-- } /gui editable.